package com.crazy.crazytransactionservice.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crazy.crazycommon.common.ErrorCode;
import com.crazy.crazycommon.constant.TransactionStatusConstant;
import com.crazy.crazycommon.constant.TransactionTypeConstant;
import com.crazy.crazycommon.exception.BusinessException;
import com.crazy.crazycommon.utils.ConfirmDateUtils;
import com.crazy.crazymodel.model.dto.trade.TradeRequest;
import com.crazy.crazymodel.model.entity.Customer;
import com.crazy.crazymodel.model.entity.Position;
import com.crazy.crazymodel.model.entity.Product;
import com.crazy.crazymodel.model.entity.Transaction;
import com.crazy.crazymodel.model.vo.RedeemVO;
import com.crazy.crazyserviceclient.service.BusinessFeignClient;
import com.crazy.crazyserviceclient.service.ProductFeignClient;
import com.crazy.crazyserviceclient.service.UserFeignClient;
import com.crazy.crazytransactionservice.mapper.TransactionMapper;
import com.crazy.crazytransactionservice.service.PositionService;
import com.crazy.crazytransactionservice.service.RedeemService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;

@Service
@Slf4j
public class RedeemServiceImpl extends ServiceImpl<TransactionMapper, Transaction> implements RedeemService {
    @Resource
    private UserFeignClient userFeignClient;
    @Resource
    private ProductFeignClient productFeignClient;
    @Resource
    private TransactionMapper transactionMapper;
    @Resource
    private BusinessFeignClient businessFeignClient;
    @Autowired
    PositionService positionService;
    @Override
    @Transactional
    public RedeemVO redeem(int customerID, int productID, BigDecimal share,String bankCardNumber) {
        //用feignCient获取客户实体，产品实体, 持仓份额
        Customer customer = userFeignClient.getById(customerID);
        Product product = productFeignClient.getById(productID);

        // 客户不存在
        if (customer == null) {
            log.info("赎回时，客户不存在");
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "客户不存在");
        }
        //产品不存在
        if (product == null) {
            log.info("赎回时，产品不存在");
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "产品不存在");
        }

        //获取用户持仓该产品的 可赎回份额
        Position position=positionService.getPosition(customerID,productID,bankCardNumber);
        //可赎回份额 为 持有份额-冻结份额
        BigDecimal validShare=position.getShare().subtract((position.getFreezeShare()==null)?BigDecimal.valueOf(0):position.getFreezeShare());

        //判断赎回份额是否大于持仓份额数
        if(share.compareTo(validShare)>0){
            log.info("赎回份额大于持仓份额，抛出异常");
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "赎回份额大于持仓份额");
        }

        //加入到交易数据库中
        Date orderTime = new Date(System.currentTimeMillis());
        Transaction transaction = new Transaction();
        transaction.setCustomerID(customerID);
        transaction.setProductID(productID);
        transaction.setBankCardNumber(bankCardNumber);
        transaction.setTransactionType(TransactionTypeConstant.REDEEM);
        transaction.setShare(share);
        transaction.setStatus(TransactionStatusConstant.PENDING);
        transaction.setTransactionTime(orderTime);
        transactionMapper.insert(transaction);

        //更新持仓表里 冻结份额数
        positionService.FreezeShares(customerID,productID,share,bankCardNumber);

        RedeemVO redeemVO=new RedeemVO();
        redeemVO.setOrderTime(orderTime);
        redeemVO.setConfirmTime(ConfirmDateUtils.calculateConfirmTime(orderTime));
        redeemVO.setTransactionId(transaction.getTransactionId());

        return redeemVO;

    }

    /**
     * 确认赎回
     * @param transactionId
     */
    @Override
    @Transactional
    public void confirmRedeem(int transactionId) {

        Transaction transaction = transactionMapper.selectById(transactionId);
        if (transaction == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "确认赎回订单不存在");
        }
        int status = transaction.getStatus();
        int transactionType = transaction.getTransactionType();

        if (status != TransactionStatusConstant.PENDING)
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "订单状态错误，确认失败");
        if (transactionType != TransactionTypeConstant.REDEEM)
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "当前订单非赎回订单，确认失败");

        BigDecimal share=transaction.getShare();//赎回份额 已被冻结
        int customerID = transaction.getCustomerID();
        int productID = transaction.getProductID();
        String bankCardNumber = transaction.getBankCardNumber();

        //根据产品ID查询当日净值
        BigDecimal networth = businessFeignClient.getNetWorthByProductID(productID);
        //赎回金额
        BigDecimal amount =networth.multiply(share);

        //更新持仓表  更新持仓表中 份额、冻结份额和持仓金额
        try{
            positionService.confirmRedeem(customerID,productID,share,amount,bankCardNumber);
        }catch (Exception e) {
            throw new RuntimeException(e);
        }

        //赎回金额加到银行卡余额里
        TradeRequest tradeRequest=new TradeRequest();
        tradeRequest.setAmount(amount);
        tradeRequest.setBankCardId(bankCardNumber);
        businessFeignClient.redeem(tradeRequest);

        //更新交易表
        transaction.setStatus(TransactionStatusConstant.COMPLETE);
        transaction.setCompleteTime(new Date(System.currentTimeMillis()));
        transactionMapper.updateById(transaction);
    }
}
